package net.cloudcodex.client.storyboard.player.presenter;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.cloudcodex.client.character.view.panel.CharacterPanel;
import net.cloudcodex.client.storyboard.player.PlayerBoardEventBus;
import net.cloudcodex.client.storyboard.player.view.SceneView;
import net.cloudcodex.client.storyboard.player.view.SceneViewImpl;
import net.cloudcodex.client.widgets.CharacterAvatar;
import net.cloudcodex.shared.dto.campaign.character.CharacterHeaderDTO;
import net.cloudcodex.shared.dto.msg.MessageDTO;
import net.cloudcodex.shared.dto.msg.SceneDTO;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.mvp4g.client.annotation.Presenter;
import com.mvp4g.client.presenter.BasePresenter;

@Presenter(view = SceneViewImpl.class, multiple = true)
public class ScenePresenter extends BasePresenter<SceneView, PlayerBoardEventBus> {
	private final Map<Long, MessagePresenter> messagePresenters = new HashMap<Long, MessagePresenter>();
	private final Map<Long, CharacterHeaderDTO> characters = new HashMap<Long, CharacterHeaderDTO>();

	private PlayerBoardPresenter parent;
	private SceneDTO scene;

	@Override
	public void bind() {

	}
	
	public void mergeScene(SceneDTO sceneToMerge) {
		if (this.scene == null) {
			// Init
			this.scene = sceneToMerge;

			// Characters
			final StringBuilder sb = new StringBuilder("characterHeader.getName()");
			final List<CharacterHeaderDTO> characters = sceneToMerge.getCharacters();
			for (CharacterHeaderDTO characterHeader : characters) {
				this.characters.put(characterHeader.getId(), characterHeader);
				
				this.view.addCharacter(characterHeader.getName(), characterHeader.getIcon(),characterHeader.getId()).addClickHandler(new ClickHandler() {
					
					@Override
					public void onClick(ClickEvent event) {
						CharacterAvatar clickedAvatar = (CharacterAvatar) event.getSource();
						CharacterHeaderDTO clickedCharacterHeaderDTO = getCharacter(clickedAvatar.getId());
						CharacterHeaderDTO ownerSelectedCharacterHeaderDTO = getCharacter(getParent().getCharacterId() );
						if (clickedAvatar.getId().longValue() == getParent().getCharacterId()){	
							eventBus.selectCharacterTab(clickedAvatar.getId(),CharacterPanel.CHARACTER_SHEET);
						}else {
							eventBus.showCharacterDescriptionPopup(getParent().getCampaignId(),ownerSelectedCharacterHeaderDTO ,clickedCharacterHeaderDTO);
						}

					}
				});
				sb.append(characterHeader.getName());
			}
		} else {
			// Update
		}

		final List<MessageDTO> messages = sceneToMerge.getMessages();
		if (messages != null) {
			for (MessageDTO message : messages) {
				final Long messageId = message.getId();
				final boolean isDeleted = message.isDeleted();
				final MessagePresenter messagePresenter = messagePresenters.get(messageId);
				if (messagePresenter == null && !isDeleted) {
					// No need to create a MessagePresenter if message is
					// deleted
					// (FIXME: Is server send not-known deleted messages?)
					this.createMessagePresenter(message);
				} else if (messagePresenter != null) {
					if (isDeleted) {
						this.eventBus.removeHandler(messagePresenter);
						this.messagePresenters.remove(messageId);
						this.view.removeMessage(messagePresenter.getView());
					} else {
						messagePresenter.mergeMessage(message);
					}
				}
			}
		}
	}

	public void moveMessage(int fromIndex, int toIndex) {
		this.view.moveMessage(fromIndex, toIndex);
	}

	public CharacterHeaderDTO getCharacter(long characterId) {
		return this.characters.get(characterId);
	}

	public PlayerBoardPresenter getParent() {
		return this.parent;
	}

	public void setParent(PlayerBoardPresenter parent) {
		this.parent = parent;
	}

	public SceneDTO getScene() {
		return scene;
	}

	private MessagePresenter createMessagePresenter(MessageDTO message) {
		final MessagePresenter messagePresenter = this.eventBus.addHandler(MessagePresenter.class);
		messagePresenter.setParent(this);
		this.messagePresenters.put(message.getId(), messagePresenter);
		this.view.insertMessage(messagePresenter.getView(), (int) message.getIndex());
		messagePresenter.mergeMessage(message);
		return messagePresenter;
	}
}
